﻿using CPPEI.Coolzon.Common;
using CPPEI.Coolzon.Core;
using CPPEI.Coolzon.Core.Data;
using CPPEI.Coolzon.Core.Repositories;
using CPPEI.Coolzon.Data;
using CPPEI.Coolzon.Data.MainServiceData;
using CPPEI.Coolzon.Metadata;
using CPPEI.Coolzon.Server.CacheData;
using CPPEI.Coolzon.Service;
using CPPEI.Coolzon.Service.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.Coolzon.Server.ServiceImplement
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Reentrant)]
    public class MainService : IMainService
    {
        public void SendRequest(Data.MainServiceData.Request request)
        {
            if (request.Header.Scenario != Coolzon.Service.Contract.SCENARIO.CONNECT && request.Header.Command != Coolzon.Service.Contract.COMMAND.CONNECT.UPLOADVIEWSTATE)
            {
                Logger.InfoToTag("MainService", string.Format("处理请求Scenario:{0:X00},Command:{1:X00},用户:{2},预期回应次数:{3}",
                    request.Header.Scenario,
                    request.Header.Command,
                    request.Header.UserIdentity,
                    request.Header.ExpectantResponseCount));
            }
            CacheDataUtil.UpdateClientLatestActiveTicks(CacheData.ServerData.Instance, request.Header.UserIdentity);

            IRequestHandler objIRequestHandler = RequestHandlerFactory.CreateHandler(request.Header.Scenario, request.Header.Command);
            Response response = null;

            if(string.IsNullOrEmpty(request.Header.UserIdentity))
            {
                response = objIRequestHandler.OnHandle(request);
                if (response == null)
                {
                    return;
                }
                // sent to self
                IMainServiceCallback callback = OperationContext.Current.GetCallbackChannel<IMainServiceCallback>();

                try
                {
                    callback.OnReceiveResponse(response);
                    //Logger.InfoToTag("MainService", string.Format("默认回应自己,Scenario:{0:X00},Command:{1:X00},用户:{2}",
                    //    request.Header.Scenario,
                    //    request.Header.Command,
                    //    response.Header.RequestHeader.UserIdentity));
                }
                catch (Exception ex)
                {
                    Logger.ErrorToTag("MainService", string.Format("默认回应自己,Scenario:{0:X00},Command:{1:X00},用户:{2},发生错误:{3}",
                        request.Header.Scenario,
                        request.Header.Command,
                        response.Header.RequestHeader.UserIdentity,
                        ex));
                }
            }
            else if (request.Header.Mode == Service.Contract.REQUEST_MODE.SELF)
            {
                #region to self
                response = objIRequestHandler.OnHandle(request);
                if (response == null)
                {
                    return;
                }
                // self
                Client user = ServerData.Instance.GetClient(request.Header.UserIdentity);
                if (user == null)
                {
                    IMainServiceCallback callback = OperationContext.Current.GetCallbackChannel<IMainServiceCallback>();
                    try
                    {
                        callback.OnReceiveResponse(response);
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorToTag("MainService", string.Format("只回应自己,Scenario:{0:X00},Command:{1:X00},来自域:{2},用户:{3},发生错误:{4}",
                            request.Header.Scenario,
                            request.Header.Command,
                            response.Header.RequestHeader.DomainId,
                            response.Header.RequestHeader.UserIdentity,
                            ex));
                    }
                }
                else
                {
                    try
                    {
                        user.Callback.OnReceiveResponse(response);
                    }
                    catch (Exception ex)
                    {
                        user.Callback = null;
                        Logger.ErrorToTag("MainService", string.Format("只回应自己,Scenario:{0:X00},Command:{1:X00},来自域:{2},用户:{3},发生错误:{4}",
                            request.Header.Scenario,
                            request.Header.Command,
                            response.Header.RequestHeader.DomainId,
                            response.Header.RequestHeader.UserIdentity,
                            ex));
                    }
                }

                #endregion
            }
            else if (request.Header.Mode == Service.Contract.REQUEST_MODE._OTHER)
            {
                CacheData.ControlDomain domain = ServerData.Instance.GetDomain(request.Header.DomainId);
                if (domain.OperatorIdentity == request.Header.UserIdentity)
                {
                    response = objIRequestHandler.OnHandle(request);
                    if (response == null)
                    {
                        return;
                    }
                    List<CacheData.Client> clientList = domain.GetClientList();

                    // 通知其他各个客户端场景事件
                    for (int index = 0; index < clientList.Count; index++)
                    {
                        CacheData.Client client = clientList[index];
                        if (client.Callback != null
                            && client.State == ClientState.InDomain
                            && client.UserIdentity != request.Header.UserIdentity)
                        {
                            try
                            {
                                client.Callback.OnReceiveResponse(response);
                            }
                            catch (Exception ex)
                            {
                                client.Callback = null;
                                Logger.ErrorToTag("MainService", "Mode:ToOther,转送来自Client:{6},Scenario:{0:X00},Command:{1:X00},DomainId:{2}到客户端:{3}时出错!{4}ex:{5}",
                                    request.Header.Scenario,
                                    request.Header.Command,
                                    response.Header.RequestHeader.DomainId,
                                    client.UserIdentity,
                                    Environment.NewLine,
                                    ex.ToString(),
                                    request.Header.UserIdentity);
                            }
                        }
                    }
                }
                else
                {
                    // 不是操作员无法发送信息
                    Logger.ErrorToTag("MainService", "client:{0}不是操作员，无法发送指令给其他用户", request.Header.UserIdentity);
                }
                //Logger.InfoToTag("MainService", string.Format("处理完毕,来自域:{0},用户:{1}发送的事件", response.Header.RequestHeader.DomainId, response.Header.RequestHeader.UserIdentity));
            }
            else if (request.Header.Mode == Service.Contract.REQUEST_MODE.NORESPONSE)
            {
                response = objIRequestHandler.OnHandle(request);
                //Logger.InfoToTag("MainService", string.Format("处理完毕,来自域:{0},用户:{1}发送的事件, 不回复", response.Header.RequestHeader.DomainId, response.Header.RequestHeader.UserIdentity));
            }
            else if (request.Header.Mode == Service.Contract.REQUEST_MODE.UNDERCONTROL_AND_INDOMAIN)
            {
                CacheData.ControlDomain domain = ServerData.Instance.GetDomain(request.Header.DomainId);
                if (domain.OperatorIdentity == request.Header.UserIdentity)
                {
                    response = objIRequestHandler.OnHandle(request);
                    if (response == null)
                    {
                        return;
                    }

                    List<CacheData.Client> clientList = domain.GetClientList();

                    // 通知各个受控制的客户端
                    for (int index = 0; index < clientList.Count; index++)
                    {
                        CacheData.Client client = clientList[index];
                        if (client.Callback != null
                            && client.State == ClientState.InDomain
                            && client.ControlState == ControlState.UnderControl)
                        {
                            try
                            {
                                client.Callback.OnReceiveResponse(response);
                            }
                            catch (Exception ex)
                            {
                                client.Callback = null;
                                Logger.ErrorToTag("MainService", "Mode:ToUNDERCONTROL_AND_INDOMAIN,转送来自Client:{6},Scenario:{0:X00},Command:{1:X00},DomainId:{2}到客户端:{3}时出错!{4}ex:{5}",
                                    request.Header.Scenario,
                                    request.Header.Command,
                                    response.Header.RequestHeader.DomainId,
                                    client.UserIdentity,
                                    Environment.NewLine,
                                    ex.ToString(),
                                    request.Header.UserIdentity);
                            }
                        }
                    }
                }
                else
                {
                    // 不是操作员无法发送信息
                    Logger.ErrorToTag("MainService", "client:{0}不是操作员，无法发送指令", request.Header.UserIdentity);
                }
            }
            else if (request.Header.Mode == Service.Contract.REQUEST_MODE.UNDERCONTROL)
            {
                CacheData.ControlDomain domain = ServerData.Instance.GetDomain(request.Header.DomainId);
                if (domain == null)
                {
                    Logger.ErrorToTag("MainService", "client:{0},域:{1}没有找到，无法发送指令", request.Header.UserIdentity, request.Header.DomainId);
                }
                else if (domain.OperatorIdentity == request.Header.UserIdentity)
                {
                    response = objIRequestHandler.OnHandle(request);
                    if (response == null)
                    {
                        return;
                    }

                    List<CacheData.Client> clientList = domain.GetClientList();

                    // 通知各个受控制的客户端
                    for (int index = 0; index < clientList.Count; index++)
                    {
                        CacheData.Client client = clientList[index];
                        if (client.Callback != null
                            && client.ControlState == ControlState.UnderControl)
                        {
                            try
                            {
                                client.Callback.OnReceiveResponse(response);
                            }
                            catch (Exception ex)
                            {
                                client.Callback = null;
                                Logger.ErrorToTag("MainService", "Mode:ToUnderControl,转送来自Client:{6},Scenario:{0:X00},Command:{1:X00},DomainId:{2}到客户端:{3}时出错!{4}ex:{5}",
                                    request.Header.Scenario,
                                    request.Header.Command,
                                    response.Header.RequestHeader.DomainId,
                                    client.UserIdentity,
                                    Environment.NewLine,
                                    ex.ToString(),
                                    request.Header.UserIdentity);
                            }
                        }
                    }
                }
                else
                {
                    // 不是操作员无法发送信息
                    Logger.ErrorToTag("MainService", "client:{0}不是操作员，无法发送指令", request.Header.UserIdentity);
                }
            }
            else
            {
                CacheData.ControlDomain domain = ServerData.Instance.GetDomain(request.Header.DomainId);

                if (domain == null)
                {
                    Logger.ErrorToTag("MainService", "client:{0},域:{1}没有找到，无法发送指令", request.Header.UserIdentity, request.Header.DomainId);
                }
                else if (domain.OperatorIdentity == request.Header.UserIdentity)
                {
                    response = objIRequestHandler.OnHandle(request);
                    if (response == null)
                    {
                        return;
                    }

                    List<CacheData.Client> clientList = domain.GetClientList();

                    // 通知各个客户端场景事件
                    for (int index = 0; index < clientList.Count; index++)
                    {
                        CacheData.Client client = clientList[index];
                        if (client.Callback != null
                            && client.State == ClientState.InDomain)
                        {
                            try
                            {
                                client.Callback.OnReceiveResponse(response);
                            }
                            catch (Exception ex)
                            {
                                client.Callback = null;
                                Logger.ErrorToTag("MainService", "Mode:ToAll,转送来自Client:{6},Scenario:{0:X00},Command:{1:X00},DomainId:{2}到客户端:{3}时出错!{4}ex:{5}",
                                    request.Header.Scenario,
                                    request.Header.Command,
                                    response.Header.RequestHeader.DomainId,
                                    client.UserIdentity,
                                    Environment.NewLine,
                                    ex.ToString(),
                                    request.Header.UserIdentity);
                            }
                        }
                    }
                }
                else
                {
                    // 不是操作员无法发送信息
                    Logger.ErrorToTag("MainService", "client:{0}不是操作员，无法发送指令", request.Header.UserIdentity);
                }
                //Logger.InfoToTag("MainService", string.Format("处理完毕,来自域:{0},用户:{1}发送的事件", response.Header.RequestHeader.DomainId, response.Header.RequestHeader.UserIdentity));
            }
        }

        public Response ExecuteRequest(Request request)
        {
            //Logger.InfoToTag("MainService", string.Format("执行请求Scenario:{0:X00},Command:{1:X00},用户:{2},预期回应次数:{3}",
            //    request.Header.Scenario,
            //    request.Header.Command,
            //    request.Header.UserIdentity,
            //    request.Header.ExpectantResponseCount));
            CacheDataUtil.UpdateClientLatestActiveTicks(CacheData.ServerData.Instance, request.Header.UserIdentity);

            IRequestHandler objIRequestHandler = RequestHandlerFactory.CreateHandler(request.Header.Scenario, request.Header.Command);
            Response response = objIRequestHandler.OnHandle(request);

            if (string.IsNullOrEmpty(request.Header.UserIdentity))
            {
                //Logger.InfoToTag("MainService", string.Format("处理完毕,用户:{0}发送的事件,只将回应信息发送给自己", response.Header.RequestHeader.UserIdentity));
                return response;
            }
            else if (request.Header.Mode == Service.Contract.REQUEST_MODE.SELF)
            {
                // self
                //Logger.InfoToTag("MainService", string.Format("处理完毕,来自域:{0},用户:{1}发送的事件,只将回应信息发送给自己", response.Header.RequestHeader.DomainId, response.Header.RequestHeader.UserIdentity));
                return response;
            }
            else if (request.Header.Mode == Service.Contract.REQUEST_MODE._OTHER)
            {
                CacheData.ControlDomain domain = ServerData.Instance.GetDomain(request.Header.DomainId);
                List<CacheData.Client> clientList = domain.GetClientList();

                // 通知其他各个客户端场景事件
                for (int index = 0; index < clientList.Count; index++)
                {
                    CacheData.Client client = clientList[index];
                    if (client.Callback != null && client.UserIdentity != request.Header.UserIdentity)
                    {
                        try
                        {
                            client.Callback.OnReceiveResponse(response);
                        }
                        catch (Exception ex)
                        {
                            client.Callback = null;
                            Logger.ErrorToTag("MainService", "转送客户端{0}时出错:{1}", client.UserIdentity, ex.ToString());
                        }
                    }
                }
                return null;
            }
            else if (request.Header.Mode == Service.Contract.REQUEST_MODE.NORESPONSE)
            {
                //Logger.InfoToTag("MainService", string.Format("处理完毕,来自域:{0},用户:{1}发送的事件, 不回复", response.Header.RequestHeader.DomainId, response.Header.RequestHeader.UserIdentity));
                return null;
            }
            else
            {
                CacheData.ControlDomain domain = ServerData.Instance.GetDomain(request.Header.DomainId);
                List<CacheData.Client> clientList = domain.GetClientList();

                // 通知其他各个客户端场景事件
                for (int index = 0; index < clientList.Count; index++)
                {
                    CacheData.Client client = clientList[index];
                    if (client.Callback != null && client.UserIdentity != request.Header.UserIdentity)
                    {
                        try
                        {
                            client.Callback.OnReceiveResponse(response);
                        }
                        catch (Exception ex)
                        {
                            client.Callback = null;
                            Logger.ErrorToTag("MainService", "转送客户端{0}时出错{1}{2}", client.UserIdentity, Environment.NewLine, ex.ToString());
                        }
                    }
                }
                return response; 
            }
        }
    }
}
